package com.uduemc.biso.node.module.common.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.node.core.common.sysconfig.FaqSysConfig;
import com.uduemc.biso.node.core.entities.SCategories;
import com.uduemc.biso.node.core.entities.SCategoriesQuote;
import com.uduemc.biso.node.core.entities.SFaq;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.entities.custom.CategoryQuote;
import com.uduemc.biso.node.core.entities.custom.Faq;
import com.uduemc.biso.node.core.utils.SystemConfigUtil;
import com.uduemc.biso.node.module.common.mapper.CCategoriesMapper;
import com.uduemc.biso.node.module.common.mapper.CFaqMapper;
import com.uduemc.biso.node.module.common.mapper.CSeoItemMapper;
import com.uduemc.biso.node.module.common.service.CFaqService;
import com.uduemc.biso.node.module.service.SCategoriesQuoteService;
import com.uduemc.biso.node.module.service.SCategoriesService;
import com.uduemc.biso.node.module.service.SFaqService;
import com.uduemc.biso.node.module.service.SSystemService;

import cn.hutool.core.collection.CollUtil;

@Service
public class CFaqServiceImpl implements CFaqService {

	@Autowired
	private CFaqMapper cFaqMapper;

	@Autowired
	private SFaqService sFaqServiceImpl;

	@Autowired
	private SSystemService sSystemServiceImpl;

	@Autowired
	private SCategoriesQuoteService sCategoriesQuoteServiceImpl;

	@Autowired
	private SCategoriesService sCategoriesServiceImpl;

	@Autowired
	private CCategoriesMapper cCategoriesMapper;

	@Autowired
	private CSeoItemMapper cSeoItemMapper;

	@Override
	@Transactional
	public Faq insert(Faq faq) {
		SFaq sFaq = faq.getSFaq();

		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(sFaq.getSystemId(), sFaq.getHostId(), sFaq.getSiteId());
		if (sSystem == null) {
			throw new RuntimeException("系统未找到 systemId: " + sFaq.getSystemId());
		}
		faq.setSSystem(sSystem);

		SFaq insertSFaq = sFaqServiceImpl.insert(sFaq);
		faq.setSFaq(insertSFaq);

		// 插入分类
		CategoryQuote categoryQuote = faq.getCategoryQuote();
		if (categoryQuote != null && categoryQuote.getSCategoriesQuote() != null) {
			SCategoriesQuote sCategoriesQuote = categoryQuote.getSCategoriesQuote();
			SCategories sCategories = sCategoriesServiceImpl.findOne(sCategoriesQuote.getCategoryId());
			if (sCategories == null || sCategories.getSystemId().longValue() != insertSFaq.getSystemId().longValue()) {
				throw new RuntimeException("系统未找到 sCategoriesQuote.getCategoryId(): " + sCategoriesQuote.getCategoryId());
			}
			sCategoriesQuote.setAimId(insertSFaq.getId());
			SCategoriesQuote insertSCategoriesQuote = sCategoriesQuoteServiceImpl.insert(sCategoriesQuote);
			categoryQuote.setSCategoriesQuote(insertSCategoriesQuote);
			categoryQuote.setSCategories(sCategories);
			faq.setCategoryQuote(categoryQuote);
		}
		return faq;
	}

	@Override
	@Transactional
	public Faq update(Faq faq) {
		SFaq sFaq = faq.getSFaq();

		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(sFaq.getSystemId(), sFaq.getHostId(), sFaq.getSiteId());
		if (sSystem == null) {
			throw new RuntimeException("系统未找到 systemId: " + sFaq.getSystemId());
		}
		faq.setSSystem(sSystem);

		SFaq findOne = sFaqServiceImpl.findOne(sFaq.getId());
		if (findOne == null) {
			throw new RuntimeException("系统未找到 SFaq findOne 数据，sFaq.getId()：" + sFaq.getId());
		}
		// 修改的数据
		findOne.setTitle(sFaq.getTitle()).setInfo(sFaq.getInfo()).setRewrite(sFaq.getRewrite()).setConfig(sFaq.getConfig()).setOrderNum(sFaq.getOrderNum())
				.setReleasedAt(sFaq.getReleasedAt());

		SFaq updateSFaq = sFaqServiceImpl.updateAllById(findOne);
		faq.setSFaq(updateSFaq);

		// 修改分类
		// 判断是否需要修改
		List<SCategoriesQuote> findBySystemAimId = sCategoriesQuoteServiceImpl.findBySystemAimId(findOne.getSystemId(), findOne.getId());
		if (CollectionUtils.isEmpty(findBySystemAimId)) {
			CategoryQuote categoryQuote = faq.getCategoryQuote();
			if (categoryQuote != null && categoryQuote.getSCategoriesQuote() != null) {
				SCategoriesQuote sCategoriesQuote = categoryQuote.getSCategoriesQuote();
				SCategories sCategories = sCategoriesServiceImpl.findOne(sCategoriesQuote.getCategoryId());
				if (sCategories == null || sCategories.getSystemId().longValue() != updateSFaq.getSystemId().longValue()) {
					throw new RuntimeException("系统未找到 sCategoriesQuote.getCategoryId(): " + sCategoriesQuote.getCategoryId());
				}
				sCategoriesQuote.setAimId(updateSFaq.getId());
				SCategoriesQuote insertSCategoriesQuote = sCategoriesQuoteServiceImpl.insert(sCategoriesQuote);
				categoryQuote.setSCategoriesQuote(insertSCategoriesQuote);

				categoryQuote.setSCategories(sCategories);

				faq.setCategoryQuote(categoryQuote);
			}
		} else if (findBySystemAimId.size() == 1) {
			SCategoriesQuote sCategoriesQuote = findBySystemAimId.get(0);

			CategoryQuote categoryQuote = faq.getCategoryQuote();
			if (categoryQuote == null || categoryQuote.getSCategoriesQuote() == null) {
				sCategoriesQuoteServiceImpl.deleteBySystemAimId(findOne.getSystemId(), findOne.getId());
				faq.setCategoryQuote(null);
			} else {
				SCategories sCategories = sCategoriesServiceImpl.findOne(categoryQuote.getSCategoriesQuote().getCategoryId());
				if (sCategories == null || sCategories.getSystemId().longValue() != updateSFaq.getSystemId().longValue()) {
					throw new RuntimeException("系统未找到 sCategoriesQuote.getCategoryId(): " + sCategoriesQuote.getCategoryId());
				}
				if (sCategoriesQuote.getCategoryId().longValue() != categoryQuote.getSCategoriesQuote().getCategoryId().longValue()) {
					// 修改 SCategoriesQuote 中的 category_id 数据
					sCategoriesQuote.setCategoryId(categoryQuote.getSCategoriesQuote().getCategoryId());
					SCategoriesQuote updateByIdSCategoriesQuote = sCategoriesQuoteServiceImpl.updateById(sCategoriesQuote);
					categoryQuote.setSCategoriesQuote(updateByIdSCategoriesQuote);
				}
				categoryQuote.setSCategories(sCategories);
				faq.setCategoryQuote(categoryQuote);
			}

		} else {
			// 清除该Faq下的原有分类数据
			boolean deleteBySystemAimId = sCategoriesQuoteServiceImpl.deleteBySystemAimId(findOne.getSystemId(), findOne.getId());
			if (!deleteBySystemAimId) {
				throw new RuntimeException("删除原有的分类引用数据出错");
			}
			CategoryQuote categoryQuote = faq.getCategoryQuote();
			if (categoryQuote != null && categoryQuote.getSCategoriesQuote() != null) {
				SCategoriesQuote sCategoriesQuote = categoryQuote.getSCategoriesQuote();
				SCategories sCategories = sCategoriesServiceImpl.findOne(sCategoriesQuote.getCategoryId());
				if (sCategories == null || sCategories.getSystemId().longValue() != updateSFaq.getSystemId().longValue()) {
					throw new RuntimeException("系统未找到 sCategoriesQuote.getCategoryId(): " + sCategoriesQuote.getCategoryId());
				}
				sCategoriesQuote.setAimId(updateSFaq.getId());
				SCategoriesQuote insertSCategoriesQuote = sCategoriesQuoteServiceImpl.insert(sCategoriesQuote);
				categoryQuote.setSCategoriesQuote(insertSCategoriesQuote);
				categoryQuote.setSCategories(sCategories);
				faq.setCategoryQuote(categoryQuote);
			}
		}

		return faq;
	}

	@Override
	public Faq findByHostSiteFaqId(long hostId, long siteId, long faqId) {
		Faq faq = new Faq();

		SFaq sFaq = sFaqServiceImpl.findByHostSiteFaqId(hostId, siteId, faqId);
		if (sFaq == null) {
			return null;
		}
		faq.setSFaq(sFaq);

		// 获取分类信息数据
		List<SCategoriesQuote> listSCategoriesQuote = sCategoriesQuoteServiceImpl.findBySystemAimId(sFaq.getSystemId(), sFaq.getId());
		if (!CollectionUtils.isEmpty(listSCategoriesQuote)) {
			SCategoriesQuote sCategoriesQuote = listSCategoriesQuote.get(0);
			SCategories sCategories = sCategoriesServiceImpl.findOne(sCategoriesQuote.getCategoryId());
			if (sCategories != null) {
				CategoryQuote categoryQuote = new CategoryQuote();
				categoryQuote.setSCategories(sCategories);
				categoryQuote.setSCategoriesQuote(sCategoriesQuote);
				faq.setCategoryQuote(categoryQuote);
			}
		}

		// 获取系统数据
		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(sFaq.getSystemId(), sFaq.getHostId(), sFaq.getSiteId());
		if (sSystem != null) {
			faq.setSSystem(sSystem);
		}

		return faq;
	}

	@Override
	public String getSFaqOrderBySSystem(SSystem sSystem) {
		if (sSystem == null || !StringUtils.hasText(sSystem.getConfig())) {
			return null;
		}
		FaqSysConfig faqSysConfig = SystemConfigUtil.faqSysConfig(sSystem);
		int orderby = faqSysConfig.getList().findOrderby();
		if (orderby == 1) {
			return "`s_faq`.`is_top` DESC, `s_faq`.`order_num` DESC, `s_faq`.`id` DESC";
		} else if (orderby == 2) {
			return "`s_faq`.`is_top` DESC, `s_faq`.`order_num` ASC, `s_faq`.`id` ASC";
		} else if (orderby == 3) {
			return "`s_faq`.`is_top` DESC, `s_faq`.`released_at` DESC, `s_faq`.`id` DESC";
		} else if (orderby == 4) {
			return "`s_faq`.`is_top` DESC, `s_faq`.`released_at` ASC, `s_faq`.`id` ASC";
		} else {
			return "`s_faq`.`is_top` DESC, `s_faq`.`order_num` DESC, `s_faq`.`id` DESC";
		}

	}

	@Override
	@Transactional
	public boolean deleteByListSFaq(List<SFaq> listSFaq) {
		if (CollectionUtils.isEmpty(listSFaq)) {
			return true;
		}
		for (SFaq sFaq : listSFaq) {
			if (sFaq.getId() != null && sFaq.getId().longValue() > 0) {
				sFaq.setIsRefuse((short) 1);
				SFaq updateById = sFaqServiceImpl.updateById(sFaq);
				if (updateById == null || updateById.getId().longValue() != sFaq.getId().longValue()) {
					throw new RuntimeException("将数据移至回收站失败，被修改的数据! sFaq: " + sFaq);
				}
			}
		}
		return true;
	}

	@Override
	@Transactional
	public boolean reductionByListSFaq(List<SFaq> listSFaq) {
		if (CollectionUtils.isEmpty(listSFaq)) {
			return true;
		}
		for (SFaq sFaq : listSFaq) {
			if (sFaq.getId() != null && sFaq.getId().longValue() > 0) {
				sFaq.setIsRefuse((short) 0);
				SFaq updateById = sFaqServiceImpl.updateById(sFaq);
				if (updateById == null || updateById.getId().longValue() != sFaq.getId().longValue()) {
					throw new RuntimeException("将回收站数据恢复失败，被修改的数据! sFaq: " + sFaq);
				}
			}
		}
		return true;
	}

	@Override
	@Transactional
	public boolean clearBySystem(SSystem sSystem) {

		// 删除 s_faq 数据
		boolean deleteBySystem = sFaqServiceImpl.deleteBySystem(sSystem);
		if (!deleteBySystem) {
			throw new RuntimeException("删除下载系统 s_faq 数据失败！ sSystem: " + sSystem);
		}

		return true;
	}

	@Override
	public int totalByHostSiteSystemCategoryIdAndRefuse(long hostId, long siteId, long systemId, long categoryId, short isRefuse) {
		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(systemId, hostId, siteId);
		if (sSystem == null) {
			return 0;
		}
		int total = 0;
		// 带有分类的情况
		if (categoryId > 0) {
			total = sFaqServiceImpl.totalByHostSiteSystemCategoryIdAndRefuse(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), categoryId, isRefuse);
		} else {
			total = sFaqServiceImpl.totalByHostSiteSystemIdAndRefuse(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), isRefuse);
		}
		return total;
	}

	@Override
	public PageInfo<SFaq> findOkInfosBySystemCategoryIdKeywordAndPage(long hostId, long siteId, long systemId, long categoryId, String keyword, int page,
			int pagesize) {
		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(systemId, hostId, siteId);
		if (sSystem == null) {
			return null;
		}
		String orderByClause = getSFaqOrderBySSystem(sSystem);
		List<Long> categoryIdList = null;
		if (categoryId != -1L) {
			categoryIdList = new ArrayList<>();
			if (categoryId > 0) {
				List<SCategories> categoriesList = sCategoriesServiceImpl.findByAncestors(categoryId);
				for (SCategories categories : categoriesList)
					categoryIdList.add(categories.getId());
			}
		}
		PageHelper.startPage(page, pagesize);
		List<SFaq> listSFaq = cFaqMapper.findOkInfosBySystemCategoryIdRefuseKeyword(hostId, siteId, systemId, categoryIdList, keyword, orderByClause);
		PageInfo<SFaq> result = new PageInfo<>(listSFaq);
		return result;
	}

	@Override
	public boolean cleanRecycle(List<SFaq> listSFaq) {

		if (CollUtil.isEmpty(listSFaq)) {
			return true;
		}
		SSystem sSystem = null;
		List<Long> ids = new ArrayList<>();
		for (SFaq sFaq : listSFaq) {
			if (sSystem == null) {
				sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(sFaq.getSystemId(), sFaq.getHostId(), sFaq.getSiteId());
			}
			Long id = sFaq.getId();
			if (id != null && id.longValue() > 0) {
				ids.add(sFaq.getId());
			}
		}

		if (sSystem == null || ids.size() < 1) {
			return false;
		}

		// 1. 删除 s_categories_quote 数据
		cCategoriesMapper.deleteRecycleSFaqSCategoryQuote(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), ids);

		// 2. 删除 s_faq 数据
		cFaqMapper.deleteRecycleSFaq(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), ids);

		// 3. 删除 s_seo_item 数据
		cSeoItemMapper.deleteRecycleSFaqSSeoItem(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), ids);

		return true;
	}

	@Override
	public boolean cleanRecycleAll(SSystem sSystem) {
		if (sSystem == null) {
			return false;
		}
		// 1. 删除 s_categories_quote 数据
		cCategoriesMapper.deleteRecycleSFaqSCategoryQuote(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), null);

		// 2. 删除 s_faq 数据
		cFaqMapper.deleteRecycleSFaq(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), null);

		// 3. 删除 s_seo_item 数据
		cSeoItemMapper.deleteRecycleSFaqSSeoItem(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId(), null);

		return true;
	}

	@Override
	public int searchOkTotal(long hostId, long siteId, long systemId, String keyword) {
		int searchTotal = cFaqMapper.searchOkTotal(hostId, siteId, systemId, keyword);
		return searchTotal;
	}

	@Override
	public PageInfo<SFaq> searchOkInfos(long hostId, long siteId, long systemId, String keyword, int page, int size) {
		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(systemId, hostId, siteId);
		if (sSystem == null) {
			return null;
		}
		String orderByClause = getSFaqOrderBySSystem(sSystem);
		PageHelper.startPage(page, size);
		List<SFaq> listSFaq = cFaqMapper.searchOkInfos(hostId, siteId, systemId, keyword, orderByClause);
		if (CollUtil.isEmpty(listSFaq)) {
			return null;
		}
		PageInfo<SFaq> result = new PageInfo<>(listSFaq);
		return result;
	}

}
